package com.cn.service.impl;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import com.cn.service.RedisLockService;
@Service(value="redisLockService")
public class RedisLockImpl implements RedisLockService {

	
	 private long lockTimeout=200; //过期200 毫秒
	 @Autowired
	 private  RedisTemplate redisTemplate;
	public long lock(final String lockKey ) {
	 try{
		        final Long lock_timeout = currtTimeForRedis() + lockTimeout + 1;
		        if ((Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
		        
		            public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
		                //定义序列化方式
		                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
		                byte[] value = serializer.serialize(lock_timeout.toString());
		                boolean flag = redisConnection.setNX(lockKey.getBytes(), value);
		                return flag;
		            }
		        })) {
		             
		            //设置超时时间，释放内存
		            redisTemplate.expire(lockKey, lockTimeout, TimeUnit.MILLISECONDS);
		            return lock_timeout;
		        } else {
		            //获取redis里面的时间
		            Long result = (Long) redisTemplate.opsForValue().get(lockKey);
		            Long currt_lock_timeout_str = result == null ? null :  result ;
		            //锁已经失效
		            if (currt_lock_timeout_str != null && currt_lock_timeout_str < System.currentTimeMillis()) {
		            	redisTemplate.delete(lockKey);
		            	
		            }
		        }
			 }catch(Exception e){
				 e.printStackTrace();
				 return -1;
	      }
        return -1;
	}

	public void unlock(String lockKey ) {
		// TODO Auto-generated method stub
	      
	        //获取redis中设置的时间
	        Long result = (Long)redisTemplate.opsForValue().get(lockKey);
	        Long currt_lock_timeout_str = result == null ? null : Long.valueOf(result);
	        //如果是加锁者，则删除锁， 如果不是，则等待自动过期，重新竞争加锁
	        if (currt_lock_timeout_str != null  ) {
	            redisTemplate.delete(lockKey);
	            
	        }
	}
	
	   public long currtTimeForRedis() {
	     /*   return (Long) redisTemplate.execute(new RedisCallback<Long>() {
	            public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {
	                return redisConnection.time();
	            }
	        });*/
		   return System.currentTimeMillis();
	    }

}
